		TITLE	OUTLDATA - Copyright (c) SLR Systems 1994

		INCLUDE	MACROS
		INCLUDE	SEGMENTS

		PUBLIC	EXE_OUT_LDATA,MOVE_LDATA_1,MOVE_LDATA_2,MOVE_LDATA_3


		.DATA

		EXTERNDEF	FIX2_LD_TYPE:BYTE

		EXTERNDEF	FIX2_LD_LENGTH:WORD

		EXTERNDEF	EXETABLE:DWORD,FIX2_SM_BASE_SEG_GINDEX:DWORD,HIGH_WATER:DWORD
		EXTERNDEF	FIX2_LDATA_PTR:DWORD,FIX2_LDATA_LOC:DWORD,FIX2_SM_LEN:DWORD,FIX2_SM_START:DWORD
		EXTERNDEF	FIX2_STACK_DELTA:DWORD

		EXTERNDEF	SEGMENT_GARRAY:STD_PTR_S


		.CODE	PASS2_TEXT

		EXTERNDEF	LIDATA_PROC:PROC,CONVERT_SUBBX_TO_EAX:PROC,ERR_ASCIZ_RET:PROC

		EXTERNDEF	DATA_OUTSIDE_SEGMOD_ERR:ABS


LIDATA_TYPE	PROC
		;
		;
		;
		MOV	EAX,FIX2_LDATA_PTR
		JMP	LIDATA_PROC

LIDATA_TYPE	ENDP


EXE_OUT_LDATA	PROC
		;
		;LDATA_PTR ETC IS RECORD TO BE WRITTEN TO SEGMOD-SPACE
		;SIMPLY MOVE IT IN ONE OR TWO BLOCK MOVES...
		;
if	fg_rom
		BITT	OMITTING_SEGMENT
		JNZ	9$
endif
		MOV	AL,FIX2_LD_TYPE
		MOV	EDX,FIX2_LDATA_LOC

		TEST	AL,MASK BIT_LI
		JNZ	LIDATA_TYPE		;OOPS, SPECIAL

		MOV	ECX,DPTR FIX2_LD_LENGTH
		MOV	EAX,FIX2_LDATA_PTR

		AND	ECX,0FFFFH

MOVE_LDATA_1	LABEL	PROC			;FROM INSTRELO, LIDATA, FORREF2
		;
		;MAKE SURE THIS RECORD DOESN'T
		;WRITE OUTSIDE SEGMOD SIZE
		;
		ADD	EDX,ECX
		JS	OHW			;FOR SHRUNK STACK BELOW ADDRESS 0, IGNORE HIGH-WATER AND LENGTH CHECK

		CMP	FIX2_SM_LEN,EDX
		JC	MOVE_LDATA_FAIL
		;
		;OK, GET READY FOR THE BIG MOVE
		;CHECK ON HIGH-WATER MARK
		;
		CMP	HIGH_WATER,EDX
		JAE	OHW

		MOV	HIGH_WATER,EDX
OHW:
		SUB	EDX,ECX

		ADD	EDX,FIX2_STACK_DELTA	;DELTA IN CASE OF STACK SEGMENT

MOVE_LDATA_2	LABEL	PROC			;FROM
		;
		;EDX IS TARGET ADDRESS
		;
		SUB	EDX,FIX2_SM_START	;DELTA FOR CURRENT SEGMOD...

MOVE_LDATA_3	LABEL	PROC			;FROM CVLIN4, FIXDS
		;
		;EAX IS SOURCE RECORD
		;ECX IS # OF BYTES
		;
		PUSHM	EDI,ESI

		MOV	EDI,EDX
		MOV	ESI,EAX

		SHR	EDX,PAGE_BITS
		AND	EDI,PAGE_SIZE-1

		PUSH	EBX
		MOV	EAX,PAGE_SIZE

		LEA	EBX,EXETABLE[EDX*4]
		SUB	EAX,EDI			;CAN WE DO THIS IN ONE MOVE?

		CMP	EAX,ECX
		JC	TWO			;NOPE, NEED TWO
TWO_1:
		CALL	CONVERT_SUBBX_TO_EAX	;GET ES PTR

		GETT	BL,MOVE_BYTES
		ADD	EDI,EAX

		OR	BL,BL
		JNZ	L6$

		OPTI_MOVSB

		MOV	EAX,ESI
		POPM	EBX,ESI,EDI

		RET

L6$:
		REP	MOVSB

		MOV	EAX,ESI
		POPM	EBX,ESI,EDI
L9$:
		RET

MOVE_LDATA_FAIL:
		ADD	EAX,ECX			;UPDATE SI ANYWAY FOR LIDATA...
		MOV	ECX,FIX2_SM_BASE_SEG_GINDEX

		PUSH	EAX
		CONVERT	ECX,ECX,SEGMENT_GARRAY
		ADD	ECX,SEGMENT_STRUCT._SEG_TEXT

		MOV	AX,DATA_OUTSIDE_SEGMOD_ERR
		CALL	ERR_ASCIZ_RET

		POP	EAX
		RET

TWO:
		;
		;OOPS, CROSSES A 16K BLOCK BOUNDARY...	DO TWO MOVES
		;
		CALL	TWO_PROC
		JMP	TWO_1

EXE_OUT_LDATA	ENDP


TWO_PROC	PROC	NEAR
		;
		;
		;
		SUB	ECX,EAX

		PUSH	ECX			;THIS MANY NEXT TIME
		MOV	ECX,EAX

		CALL	CONVERT_SUBBX_TO_EAX	;GET ES PTR

		GETT	DL,MOVE_BYTES
		ADD	EDI,EAX

		OR	DL,DL
		JNZ	L7$

		OPTI_MOVSB

L8$:
		POP	ECX
		ADD	EBX,4			;NEXT LOGICAL BLOCK

		XOR	EDI,EDI

		RET

L7$:
		REP	MOVSB
		JMP	L8$

TWO_PROC	ENDP


		END

